package breadbox.client.files;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * Object that represents a file chunk in the system
 * @author Forrest
 *
 */
public abstract class Chunk implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 761285385310469600L;
	protected long id;
	protected int index;					// ___ out of total
	protected int total;					// index out of ___
	protected byte[] data;
	protected String filename;
	protected boolean encryption;
	protected boolean publicfile;
	
	/**
	 * Set the total number of Chunks in the current file
	 * @param t integer total
	 */
	public void setTotal(int t) {
		this.total = t;
	}
	
	/**
	 * Get the data from a Chunk
	 * @return byte[] Chunk data
	 */
	public byte[] getData() {
		byte[] result = data.clone();
		if (encryption) {
			result = decrypt(result);
		}
		return result;
	}
	
	/**
	 * Get the index of a Chunk (Chunk index out of total)
	 * @return int index
	 */
	public int getIndex() {
		return index;
	}
	
	/**
	 * Get the total number of Chunks in the current file
	 * @return int total
	 */
	public int getTotal() {
		return total;
	}
	
	/**
	 * Get the filename the current chunk represents
	 * @return String filename
	 */
	public String getFilename() {
		return filename;
	}
	
	/**
	 * Get the ID from a Chunk
	 * @return long chunk ID
	 */
	public long getID() {
		return id; 
	}
	
	/**
	 * Serialize the current Chunk into a byte array
	 * @return byte[] representing current chunk
	 * @throws IOException
	 */
	public byte[] toByteArray() throws IOException {
		ByteArrayOutputStream byte_out = new ByteArrayOutputStream();
		ObjectOutputStream object_out = new ObjectOutputStream(byte_out);
		object_out.writeObject(this);
		object_out.flush();
		object_out.close();
		byte_out.flush();
		byte[] b = byte_out.toByteArray();
		return b;
	}

	protected byte[] encrypt(byte[] data_in) {
		// TODO: implement encryption
		return data_in;
	}
	
	protected byte[] decrypt (byte[] data_in) {
		// TODO: implement decryption
		return data_in;
	}
	
	public boolean getEncryption() {
		return this.encryption;
	}
}
